package cn.col.gszf.conf;

import cn.col.gszf.handler.CustomAuthenticationEntryPoint;
import cn.col.gszf.mapper.UserMapper;
import cn.col.gszf.model.RestResult;
import cn.col.gszf.pojo.User;
import cn.col.gszf.service.impl.UserServiceImpl;
import cn.col.gszf.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.annotation.Resource;

/**
 * @Description SpringSecurity配置类
 * @Author: wanghong
 * @Date: 2024/6/17
 */
@Configuration
@EnableWebSecurity
/*开启方法权限认证*/
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserServiceImpl userService;

    @Resource
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

//    private final TigerLogoutSuccessHandler logoutSuccessHandler = new TigerLogoutSuccessHandler("/login");

    public static final String[] NO_AUTH_LIST = {
            "/index",
            "/login",
            "/static/**",
            "/images/**",
            "/css/**",
            "/js/**",
            "/channel/**",
            "/img/**",
            "/",
            "/vote"
    };

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable().formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .permitAll()
                //失败处理
//                .failureHandler((req, resp, e) -> ResponseUtil.restResponse(resp, HttpStatus.FORBIDDEN, RestResult.error(403, e.getMessage())))
                //成功处理
//                .failureForwardUrl("/l")
                .failureUrl("/login?error=403")
                .successHandler((req, resp, e) ->
                        login()
                )
                .defaultSuccessUrl("/root")
                .permitAll()
                .and().exceptionHandling()
                //请求登录处理，改变默认跳转登录页
                .authenticationEntryPoint(customAuthenticationEntryPoint)
//                .authenticationEntryPoint((req, resp, e) -> ResponseUtil.restResponse(resp, HttpStatus.UNAUTHORIZED, RestResult.error(401, "请先登录")))
                //没有权限访问
                .accessDeniedHandler((req, resp, e) -> ResponseUtil.restResponse(resp, HttpStatus.FORBIDDEN, RestResult.error(403, "抱歉，你当前的身份无权访问")))
                //设置最大一人同时登陆
                .and().sessionManagement().maximumSessions(1)
                .expiredSessionStrategy(s -> ResponseUtil.restResponse(s.getResponse(), HttpStatus.FORBIDDEN, RestResult.error(499, "您的账号在别的地方登录，当前登录已失效")))
                .and()
                //设置登出
                .and().logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/index")
                .invalidateHttpSession(true).deleteCookies("JSESSIONID")
                .permitAll()
                .and().authorizeRequests()
                .antMatchers(NO_AUTH_LIST).permitAll()
                .antMatchers("/*.jpg", "/*.svg", "/*.png", "/*.js", "/*.css", "/*ico").permitAll()
                .and().authorizeRequests().anyRequest().authenticated();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    public User login() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setPassword("out_bbs8**#%$");
        return user;
    }


}